﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Danser_Entity.Entities;
using Excel;
using System.IO;

using Danser_Control.Exceptions;
using Danser_Control.Managers;

namespace Danser_Control.ManagersImpl
{
    /// <summary>
    /// implements the IDataImporter interface for excel files
    /// </summary>
    public class ExcelDataImporter : IDataImporter
    {

        #region IExcelDataImporter Members

        /// <see cref="Danser_Control.Managers.IDataImporter.Import"/>
        public void Import(string fileName,
            TestInfo mTestInfo,
            TestParams mTestParams,
            IList<TestResults> mResultList)
        {
            if (fileName == null) 
            {
                throw new DanserImportException("null file Name", null);
            }

            //TODO: temporary setting of test info index:
            String testInfoIndex = GetIndex(fileName);
            if (testInfoIndex == null)
            {
                throw new DanserImportException("Could not retrieve GUID", null);
            }
            mTestInfo.TestInfoIndex = testInfoIndex;
            mTestParams.TestInfoIndex = testInfoIndex;

            try
            {

                FileStream stream = File.Open(fileName, FileMode.Open, FileAccess.Read);

                IExcelDataReader excelReader = Factory.CreateReader(stream, ExcelFileType.Binary);

                DataSet result = excelReader.AsDataSet();

                excelReader.Close();


                try
                {
                    Import_TestInfo(result, mTestInfo);
                    Import_TestParams(result, mTestParams);
                    Import_TestResults(result, mResultList, testInfoIndex);
                }
                catch (Exception ex)
                {
                    throw new DanserImportException("File Parse error",ex);
                }


            }

            catch (Exception ex)
            {
                throw new DanserImportException("File IO error",ex);
            }           
        }

        #endregion

        #region local functionality

        /// <summary>
        /// This method imports the relevent fields from the dataset to the testInfo object
        /// </summary>
        /// <param name="mDataSet"></param>
        /// <param name="mTestInfo"></param>
        private void Import_TestInfo(DataSet mDataSet, TestInfo mTestInfo)
        {
            //default values for first loading of data
            mTestInfo.IsAnchor = false;
            mTestInfo.IsConfirmed = false;
            
            //TODO
            //mTestInfo.TestInfoIndex

            mTestInfo.Operator = mDataSet.Tables[0].Rows[0][1].ToString();
            mTestInfo.Date = mDataSet.Tables[0].Rows[1][1].ToString();
            mTestInfo.Time = mDataSet.Tables[0].Rows[2][1].ToString();
            mTestInfo.TestName = mDataSet.Tables[0].Rows[3][1].ToString();
            mTestInfo.APType = mDataSet.Tables[0].Rows[4][1].ToString();
            mTestInfo.APIP = mDataSet.Tables[0].Rows[5][1].ToString();
            mTestInfo.APFWVer = mDataSet.Tables[0].Rows[6][1].ToString();
            mTestInfo.NICMAC = mDataSet.Tables[0].Rows[7][1].ToString();
            mTestInfo.NICType = mDataSet.Tables[0].Rows[8][1].ToString();
            mTestInfo.ProjectName = mDataSet.Tables[0].Rows[9][1].ToString();
            mTestInfo.OS = mDataSet.Tables[0].Rows[10][1].ToString();
            mTestInfo.TIC = mDataSet.Tables[0].Rows[11][1].ToString();
            mTestInfo.SetupName = mDataSet.Tables[0].Rows[15][1].ToString();
            mTestInfo.PlatformModel = mDataSet.Tables[0].Rows[16][1].ToString();
            mTestInfo.PlatformName = mDataSet.Tables[0].Rows[17][1].ToString();
            mTestInfo.TrafficProtocol = mDataSet.Tables[0].Rows[18][1].ToString();
        }

        /// <summary>
        /// This method imports the relevent fields from the dataset to the testParams object
        /// </summary>
        /// <param name="mDataSet"></param>
        /// <param name="mTestParams"></param>
        private void Import_TestParams(DataSet mDataSet, TestParams mTestParams)
        {
            mTestParams.Band = mDataSet.Tables[0].Rows[12][1].ToString();
            mTestParams.ChannelWidth = mDataSet.Tables[0].Rows[13][1].ToString();
            mTestParams.Channel = mDataSet.Tables[0].Rows[14][1].ToString();
        }

        /// <summary>
        /// This method imports the relevent fields from the dataset to the testResult list
        /// </summary>
        /// <param name="mDataSet"></param>
        /// <param name="mResultList"></param>
        private void Import_TestResults(DataSet mDataSet, IList<TestResults> mResultList, String testInfoIndex)
        {
            int offset = 23;

            DataRow mRow = mDataSet.Tables[0].Rows[offset];

            while (mRow[1] != DBNull.Value)
            {
                TestResults newRow = new TestResults();
                newRow.TestInfoIndex = testInfoIndex;
                string[] attenArr = mRow[4].ToString().Split(',');
                int.TryParse(attenArr[0], out newRow.Attenuation);
                double.TryParse(mRow[5].ToString(), out newRow.TXMin);
                double.TryParse(mRow[6].ToString(), out newRow.TXAvg);
                double.TryParse(mRow[7].ToString(), out newRow.TXMax);
                double.TryParse(mRow[8].ToString(), out newRow.RXMin);
                double.TryParse(mRow[9].ToString(), out newRow.RXAvg);
                double.TryParse(mRow[10].ToString(), out newRow.RXMax);
                double.TryParse(mRow[11].ToString(), out newRow.RSSI1);
                double.TryParse(mRow[12].ToString(), out newRow.RSSI2);
                double.TryParse(mRow[13].ToString(), out newRow.RSSI3);

                mResultList.Add(newRow);
                mRow = mDataSet.Tables[0].Rows[++offset];
            }

        }

        private String GetIndex(String filename)
        {
            int guidStart = filename.LastIndexOf("{") + 1;
            int guidEnd = filename.LastIndexOf("}");
            if (guidStart == 0 || guidEnd == -1)
            {
                return null;
            }
            
            String guidStr = filename.Substring(guidStart, guidEnd - guidStart);
            return guidStr;

        }


        #endregion


    }
}
